package com.imooc.admin.controller;

import com.imooc.admin.service.AdminUserService;
import com.imooc.api.controller.admin.AdminMngControllerApi;
import com.imooc.api.controller.user.BaseControllerApi;
import com.imooc.enums.FaceVerifyType;
import com.imooc.exception.GraceException;
import com.imooc.grance.result.GraceJsonResult;
import com.imooc.grance.result.ResponseStatusEnum;
import com.imooc.pojo.AdminUser;
import com.imooc.pojo.bo.AdminLoginBO;
import com.imooc.pojo.bo.NewAdminBO;
import com.imooc.utils.FaceVerifyUtils;
import com.imooc.utils.PagedGridResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 *
 * @auther Levi
 * @Date: 2021/03/18/17:38
 * @Description:
 */
@RestController
public class AdminMngController extends BaseControllerApi implements AdminMngControllerApi {

    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private FaceVerifyUtils faceVerifyUtils;

    @Override
    public GraceJsonResult adminLogin( AdminLoginBO adminLoginBO,
                                      HttpServletRequest request, HttpServletResponse response) {
        String username = adminLoginBO.getUsername();
        String password = adminLoginBO.getPassword();
        //1.判断用户名密码是不是空
        if (StringUtils.isBlank(username)||StringUtils.isBlank(password)) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_USERNAME_NULL_ERROR);
        }
        AdminUser adminUser = adminUserService.queryAdminByUsername(adminLoginBO.getUsername());
        //2.
        if (adminUser == null) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_NOT_EXIT_ERROR);
        }
        //3.校验用户密码
        boolean checkpw = BCrypt.checkpw(adminLoginBO.getPassword(), adminUser.getPassword());
        if (!checkpw) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_NOT_EXIT_ERROR);
        }
        //4.用户登录成功之后保存用户token到redis中  保存用户信息到cookie中
        doLoginSettings(adminUser, request, response);
        return GraceJsonResult.ok();
    }

    @Override
    public GraceJsonResult adminIsExist(String username) {
        checkAdminExist(username);
        return GraceJsonResult.ok();
    }

    @Override
    public GraceJsonResult addNewAdmin(NewAdminBO newAdminBO) {

        String username = newAdminBO.getUsername();
        String password = newAdminBO.getPassword();
        //1.判断用户名密码是否为空
        if (StringUtils.isBlank(username)) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_USERNAME_NULL_ERROR);
        }
        //2.如果base64为空则需要用密码登录，密码不为空，也要跟确认密码一致
        if (StringUtils.isBlank(newAdminBO.getImg64())) {
            if (StringUtils.isBlank(newAdminBO.getPassword()) ||
                    !newAdminBO.getPassword().equalsIgnoreCase(newAdminBO.getConfirmPassword())) {
                return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_PASSWORD_ERROR);
            }
        }
        checkAdminExist(newAdminBO.getUsername());
        adminUserService.createAdmin(newAdminBO);

        return GraceJsonResult.ok();
    }

    @Override
    public GraceJsonResult getAdminList(Integer page, Integer pageSize) {
        if (page == null) {
            page = 1;
        }
        if (pageSize == null) {
            pageSize = 3;
        }
        PagedGridResult pagedGridResult = adminUserService.queryAdminList(page, pageSize);
        return GraceJsonResult.ok(pagedGridResult);
    }

    @Override
    public GraceJsonResult adminLogout(String adminId, HttpServletRequest request,
                                       HttpServletResponse response) {
        System.out.println("AdminID: "+adminId);
        //清空redis中admin  Token
        redis.del(REDIS_ADMIN_TOKEN+":"+adminId);
        //清空Cookie中的admin信息
        deleteCookie(request,response,ADMIN_NAME_KEY);
        deleteCookie(request,response,ADMIN_ID_KEY);
        deleteCookie(request,response,ADMIN_TOKEN_KEY);
        return GraceJsonResult.ok();
    }

    @Override
    public GraceJsonResult adminFaceLogin(AdminLoginBO adminLoginBO, HttpServletRequest request,
                                          HttpServletResponse response) {
        //1.对用户名和人脸信息进行判空
        if (StringUtils.isBlank(adminLoginBO.getUsername())) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_USERNAME_NULL_ERROR);
        }
        String img64temp = adminLoginBO.getImg64();
        if (StringUtils.isBlank(img64temp)) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_FACE_NULL_ERROR);
        }
        //2.根据用户名查询用户信息，获得用户的faceId
        AdminUser adminUser = adminUserService.queryAdminByUsername(adminLoginBO.getUsername());
        String faceId = adminUser.getFaceId();
        //FIXME  后期改为微服务调用，调用文件服务，获取人脸的base64信息
        String fileUrl = "http://files.imoocnews.com:8004/fs/readFaceInGridFS?faceId=" + faceId;
        ResponseEntity<GraceJsonResult> forEntity = restTemplate.getForEntity(fileUrl, GraceJsonResult.class);
        GraceJsonResult body = forEntity.getBody();
        String base64DB = (String)body.getData();
        //4.调用阿里api进行人脸信息比对，实现登录
        boolean result = faceVerifyUtils.faceVerify(FaceVerifyType.BASE64.type, img64temp, base64DB, 60);
        if (!result) {
            return GraceJsonResult.errorCustom(ResponseStatusEnum.ADMIN_FACE_LOGIN_ERROR);
        }
        //5.登录成功之后保存admin信息到cookie和redis
        doLoginSettings(adminUser,request,response);
        return GraceJsonResult.ok();
    }

    /**
     * 用户admin登陆过后保存admin的信息
     * @param adminUser
     * @param request
     * @param response
     */
    private void doLoginSettings(AdminUser adminUser, HttpServletRequest request,
                                 HttpServletResponse response) {
        //保存admin信息到redis中
        String atoken = UUID.randomUUID().toString();
        redis.set(REDIS_ADMIN_TOKEN+":"+adminUser.getId(),atoken);
        //保存admin信息到cookie中
        setCookie(request,response,ADMIN_TOKEN_KEY,atoken,COOKIE_MONTH);
        setCookie(request,response,ADMIN_ID_KEY,adminUser.getId(),COOKIE_MONTH);
        setCookie(request,response,ADMIN_NAME_KEY,adminUser.getAdminName(),COOKIE_MONTH);

    }

    /**
     * 该方法用于判断admin的name是否已经被注册
     * @param username
     */
    private void checkAdminExist(String username) {
        System.out.println(username);
        AdminUser adminUser = adminUserService.queryAdminByUsername(username);
        if (adminUser != null) {
            GraceException.display(ResponseStatusEnum.ADMIN_USERNAME_EXIST_ERROR);
        }
    }

}
